package com.nanhai.buddhist.college.module.collegebase.service.professions;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil;
import com.nanhai.buddhist.college.framework.common.pojo.CommonResult;
import com.nanhai.buddhist.college.framework.common.util.json.JsonUtils;
import com.nanhai.buddhist.college.framework.common.util.number.NumberUtils;
import com.nanhai.buddhist.college.framework.common.util.collection.CollectionUtils;
import com.nanhai.buddhist.college.framework.datapermission.core.annotation.DataPermission;
import com.nanhai.buddhist.college.framework.security.core.util.SecurityFrameworkUtils;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.colleges.vo.UserPermissionListVo;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.professions.vo.ProfessionsCreateReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.professions.vo.ProfessionsPageReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.professions.vo.ProfessionsUpdateReqVO;
import com.nanhai.buddhist.college.module.collegebase.convert.professions.ProfessionsConvert;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.departments.DepartmentsDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.professions.ProfessionsDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.studentroll.StudentRollDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.teacherteachers.TeacherCountDO;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.departments.DepartmentsMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.professions.ProfessionsMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.studentroll.StudentRollMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.teacherteachers.TeacherTeachersMapper;
import com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants;
import com.nanhai.buddhist.college.module.system.api.user.AdminUserApi;
import com.nanhai.buddhist.college.module.system.api.user.dto.AdminUserRespDTO;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import com.nanhai.buddhist.college.framework.common.pojo.PageResult;

import static com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants.*;

/**
 * 学校管理--专业 Service 实现类
 *
 * @author 开发
 */
@Service
@Validated
public class ProfessionsServiceImpl implements ProfessionsService {

    @Resource
    private ProfessionsMapper professionsMapper;

    @Resource
    private StudentRollMapper studentRollMapper;

    @Resource
    private DepartmentsMapper departmentsMapper;


    @Resource
    private TeacherTeachersMapper teacherTeachersMapper;

    @Resource
    private AdminUserApi adminUserApi;

    @Override
    public String createProfessions(ProfessionsCreateReqVO createReqVO) {

//        String userId = SecurityFrameworkUtils.getLoginUserId();
//        CommonResult<AdminUserRespDTO> users = adminUserApi.getUser(userId);
//        String permissionJson = users.getData().getPermissionJson();
//        UserPermissionListVo userPermissionListVo = JsonUtils.parseObject(permissionJson, UserPermissionListVo.class);
//
//        if(Objects.isNull(userPermissionListVo) || !userPermissionListVo.isProfessionAll()){
//            throw ServiceExceptionUtil.exception(ErrorCodeConstants.PROFESSION_NOT_ALLOW_CREATE);
//        }
        final Long count = professionsMapper.selectCount(new LambdaQueryWrapper<ProfessionsDO>().eq(ProfessionsDO::getDepartmentsId, createReqVO.getDepartmentsId())
                .eq(ProfessionsDO::getProfessionName, createReqVO.getProfessionName()));

        if (ObjectUtil.isNotNull(count) && count > 0) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.PROFESSIONS_NAME_HAVE_EXISTS);
        }

        String codeString = getCodeString(createReqVO);

        // 插入
        ProfessionsDO professions = ProfessionsConvert.INSTANCE.convert(createReqVO);
        professions.setProfessionCode(codeString);

        professions.setProfessionNumber(NumberUtils.getCodeByServ("ZY"));
        professionsMapper.insert(professions);
        adminUserApi.saveUserCollegeData(SecurityFrameworkUtils.getLoginUserId(), 2, createReqVO.getDepartmentsId(), professions.getId());
        adminUserApi.initUserCollegeData(SecurityFrameworkUtils.getLoginUserId());
        // 返回
        return professions.getId();
    }

    @NotNull
    private String getCodeString(ProfessionsCreateReqVO createReqVO) {
        String str = "";
        // 获取父级代码
        DepartmentsDO departmentsDO = departmentsMapper.selectById(createReqVO.getDepartmentsId());

        // 获取流水号
        ProfessionsDO professionsDO = professionsMapper.selectOne(new LambdaQueryWrapper<ProfessionsDO>().orderByDesc(ProfessionsDO::getProfessionCounter).last(" limit 1"));
        int professions = 0;
        if (ObjectUtil.isNotNull(professionsDO)) {
            professions = professionsDO.getProfessionCounter();
        }
        professions += 1;
        str = departmentsDO.getCode() + professions;
        return str;
    }


    @Override
    public void updateProfessions(ProfessionsUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateProfessionsExists(updateReqVO.getId());

        final Long count = professionsMapper.selectCount(new LambdaQueryWrapper<ProfessionsDO>()
                .eq(ProfessionsDO::getDepartmentsId, updateReqVO.getDepartmentsId())
                .eq(ProfessionsDO::getProfessionName, updateReqVO.getProfessionName())
                .ne(ProfessionsDO::getId, updateReqVO.getId()));
        if (ObjectUtil.isNotNull(count) && count > 0) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.PROFESSIONS_NAME_HAVE_EXISTS);
        }
        // 更新
        ProfessionsDO updateObj = ProfessionsConvert.INSTANCE.convert(updateReqVO);
        professionsMapper.updateById(updateObj);

        adminUserApi.initUserCollegeData(SecurityFrameworkUtils.getLoginUserId());
    }

    @Override
    public void deleteProfessions(String id) {
        // 校验存在
        this.validateProfessionsExists(id);

        if (ObjectUtil.isNotNull(adminUserApi.checkRoleUser(id).getData()) && adminUserApi.checkRoleUser(id).getData()) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.CHECK_USE_EXISTS);
        }
        // 删除
        professionsMapper.deleteById(id);

        adminUserApi.initUserCollegeData(SecurityFrameworkUtils.getLoginUserId());
    }

    private void validateProfessionsExists(String id) {
        if (professionsMapper.selectById(id) == null) {
            throw exception(PROFESSIONS_NOT_EXISTS);
        }
    }

    @Override
    @DataPermission(enable = false)
    public ProfessionsDO getProfessions(String id) {
        ProfessionsDO professionsDO = professionsMapper.selectById(id);
        DepartmentsDO departmentsDO = departmentsMapper.selectById(professionsDO.getDepartmentsId());

        professionsDO.setCollegeId(departmentsDO.getCollegeId());
        return professionsDO;
    }

    @Override
    @DataPermission(enable = false)
    public List<ProfessionsDO> getProfessionsList(Collection<String> ids) {
        return CollectionUtils.isEmpty(ids) ? Collections.emptyList() : professionsMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ProfessionsDO> getProfessionsPage(ProfessionsPageReqVO pageReqVO) {
        PageResult<ProfessionsDO> selectPage = professionsMapper.selectPage(pageReqVO);
        selectPage.getList().stream().map(ProfessionsDO::getId).collect(Collectors.toList());
        Set<String> collegeIds = CollectionUtils.convertSet(selectPage.getList(), ProfessionsDO::getCollegeId);
        Map<String, TeacherCountDO> stringTeacherCountDOMap = Collections.EMPTY_MAP;
        if (!collegeIds.isEmpty()) {
            List<TeacherCountDO> teacherCountDOS = teacherTeachersMapper.queryTeacherCountByCollegeIds(collegeIds);
            stringTeacherCountDOMap = CollectionUtils.convertMap(teacherCountDOS, TeacherCountDO::getCollegeId);
        }

        if (CollectionUtil.isNotEmpty(selectPage.getList())) {
            for (ProfessionsDO professionsDO : selectPage.getList()) {
                Long selectCount = studentRollMapper.selectCount(new LambdaUpdateWrapper<StudentRollDO>()
                        .eq(StudentRollDO::getProfessionsId, professionsDO.getId()));
                professionsDO.setStudentCount(selectCount);
                professionsDO.setTeacherCount(Optional.ofNullable(stringTeacherCountDOMap).map(s -> s.get(professionsDO.getCollegeId())).map(TeacherCountDO::getTeacherCount).orElse(0L));
            }
        }
        return selectPage;
    }

    @Override
    public List<ProfessionsDO> getProfessionsList(ProfessionsPageReqVO exportReqVO) {
        exportReqVO.setPageNo(1);
        exportReqVO.setPageSize(9999999);
        PageResult<ProfessionsDO> selectPage = professionsMapper.selectPage(exportReqVO);

        return selectPage.getList();
    }

    @Override
    public List<ProfessionsDO> getProfessionsListByDepartmentsId(String departmentsId) {
        return professionsMapper.selectList(new LambdaQueryWrapper<ProfessionsDO>().eq(ProfessionsDO::getDepartmentsId, departmentsId));
    }

}
